package com.wxy.favorites.service;

import cn.hutool.core.util.StrUtil;
import com.wxy.favorites.Application;
import com.wxy.favorites.constant.LogConstants;
import com.wxy.favorites.core.NoRollbackException;
import com.wxy.favorites.core.PageInfo;
import com.wxy.favorites.dao.SystemLogRepository;
import com.wxy.favorites.entity.SystemLog;
import com.wxy.favorites.security.ContextUtils;
import com.wxy.favorites.security.SecurityUser;
import com.wxy.favorites.util.IpUtils;
import com.wxy.favorites.util.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author wangxiaoyuan
 * @Date 2020/4/24 11:50
 * @Description
 **/
@Slf4j
@Service
@Transactional(noRollbackFor = NoRollbackException.class)
public class SystemLogService {

    @Autowired
    private SystemLogRepository systemLogRepository;

    public SystemLog save(SystemLog log) {
        return systemLogRepository.save(log);
    }

    public PageInfo<SystemLog> findPage(String content, String ip, Date startTime, Date endTime, Integer pageNum, Integer pageSize) {
        String text = SqlUtils.trimAndEscape(content);
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, "createTime"));
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.by(orders));
        // 构造自定义查询条件
        Specification<SystemLog> queryCondition = (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (StrUtil.isNotBlank(ip)) {
                predicateList.add(criteriaBuilder.equal(root.get("ip"), ip));
            }
            if (StrUtil.isNotBlank(text)) {
                predicateList.add(criteriaBuilder.like(root.get("content"), "%" + text + "%"));
            }
            if (startTime != null && endTime != null) {
                predicateList.add(criteriaBuilder.between(root.get("createTime"), startTime, endTime));
            }
            return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
        };
        Page<SystemLog> page = systemLogRepository.findAll(queryCondition, pageable);
        return new PageInfo<>(page.getContent(), page.getTotalPages(), page.getTotalElements());
    }

    public Boolean clean() {
        systemLogRepository.deleteAll();
        SecurityUser currentUser = ContextUtils.getCurrentUser();
        systemLogRepository.save(new SystemLog().setCreateTime(new Date()).setIp(IpUtils.getIp())
                .setContent(String.format(LogConstants.LOG_CLEAN_MSG, currentUser.getUsername())));
        return true;
    }

    public void shutdown() {
        SecurityUser currentUser = ContextUtils.getCurrentUser();
        systemLogRepository.save(new SystemLog().setCreateTime(new Date()).setIp(IpUtils.getIp()).setContent(String.format(LogConstants.SHUTDOWN_MSG, currentUser.getUsername())));
        Application.shutdown(5);
    }

    public void restart() {
        SecurityUser currentUser = ContextUtils.getCurrentUser();
        systemLogRepository.save(new SystemLog().setCreateTime(new Date()).setIp(IpUtils.getIp()).setContent(String.format(LogConstants.RESTART_MSG, currentUser.getUsername())));
        Application.restart(2);
    }
}

